﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace SPHelper
{
	public class Site
	{
		/// <summary>
		/// Get the SPSite site collection from the current context.
		/// DO NOT DISPOSE!!!
		/// </summary>
		/// <param name="context"></param>
		/// <returns></returns>
		public static SPSite GetSite()
		{
			SPSite site = null;
			try
			{
				// init
				if (SPContext.Current == null) { throw new Exception("SPContext is null"); }
				if (SPContext.Current.Site == null) { throw new Exception("SPSite in SPContext object is null"); }

				site = SPContext.Current.Site;
			}
			catch (Exception ex)
			{
				Log.WriteError("rsursurtyrdfcgcvr", ex);
				site = null;
			}
			return site;
		}

		/// <summary>
		/// Get a NEW instance of a site by url passed
		/// MUST DISPOSE!!!
		/// </summary>
		/// <param name="absoluteUrl"></param>
		/// <returns></returns>
		public static SPSite GetSite(string absoluteUrl)
		{
			SPSite site = null;
			try
			{
				// init
				if (string.IsNullOrEmpty(absoluteUrl)) { throw new Exception("url passed is null"); }
				if (!Validation.IsValidUrl(absoluteUrl)) { throw new Exception("url passed is not valid: " + absoluteUrl); }

				site = new SPSite(absoluteUrl);
				if (site == null) { throw new Exception("Failed to find SPSite collection using url: " + absoluteUrl); }
			}
			catch (Exception ex)
			{
				Log.WriteError("rsursurtyrdfcgcvr", ex, "absolute URL: " + absoluteUrl);
				site = null;
			}
			return site;
		}

		/// <summary>
		/// Get SPSite reference from Feature's SPFeatureReceiverProperties
		/// DO NOT DISPOSE!!!
		/// </summary>
		/// <param name="properties"></param>
		/// <returns></returns>
		public static SPSite GetSite(SPFeatureReceiverProperties properties)
		{
			SPSite site = null;
			try
			{
				// init
				if (properties == null) { throw new Exception("SPFeatureReceiverProperties passed is null"); }


				try
				{
					site = properties.Feature.Parent as SPSite;
				}
				catch
				{
					throw new Exception("Failed to cast SPFeatureReceiverProperties to an SPSite. Most likely the feature is NOT scoped to Site");
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("dt67ifry7fygdtrrtd7t86", ex);
				site = null;
			}
			return site;
		}


		/// <summary>
		/// Get SPSite from passed SPFarm object
		/// DO NOT DISPOSE!!!
		/// </summary>
		/// <param name="farm"></param>
		/// <param name="siteId"></param>
		/// <param name="isThrowErrorIfDoesntExist"></param>
		/// <returns></returns>
		public static SPSite GetSite(SPFarm farm, Guid siteId, bool isThrowErrorIfDoesntExist)
		{
			SPSite site = null;
			try
			{
				// init
				if (farm == null) { throw new Exception("SPFarm passed is null"); }
				if (siteId == null || siteId == Guid.Empty) { throw new Exception("siteId passed is an invalid guid"); }

				// farm scope
				foreach (SPService service in farm.Services)
				{
					if (service is SPWebService)
					{
						SPWebService webService = (SPWebService)service;
						foreach (SPWebApplication webApp in webService.WebApplications)
						{
							foreach (SPSite _site in webApp.Sites)
							{
								if (_site.ID == siteId)
								{
									site = _site;
									break;
								}
							}
						}
					}
				}

				if (site == null && isThrowErrorIfDoesntExist) { throw new Exception("Failed to find site using siteId: " + siteId); }
			}
			catch (Exception ex)
			{
				Log.WriteError("56eusrtdrgea4djtgh", ex);
				site = null;
			}
			return site;
		}

		/// <summary>
		/// Get SPSite from passed SPFarm and absolute url
		/// </summary>
		/// <param name="farm"></param>
		/// <param name="absoluteUrl">the full url for the </param>
		/// <param name="isThrowErrorIfDoesntExist"></param>
		/// <returns></returns>
		public static SPSite GetSite(SPFarm farm, string absoluteUrl, bool isThrowErrorIfDoesntExist)
		{
			SPSite site = null;
			try
			{
				// init
				if (farm == null) { throw new Exception("SPFarm passed is null"); }
				if (!Validation.IsValidUrl(absoluteUrl)) { throw new Exception("url passed is invalid"); }
				absoluteUrl = absoluteUrl.ToLower().Trim();

				foreach (SPService service in farm.Services)
				{
					if (service is SPWebService)
					{
						SPWebService webService = (SPWebService)service;
						foreach (SPWebApplication webApp in webService.WebApplications)
						{
							foreach (SPSite _site in webApp.Sites)
							{
								if (_site.Url.ToLower().Trim() == absoluteUrl)
								{
									site = _site;
									break;
								}
							}
						}
					}
				}

				if (site == null && isThrowErrorIfDoesntExist) { throw new Exception("Failed to find site using url: " + absoluteUrl); }
			}
			catch (Exception ex)
			{
				Log.WriteError("uilryujgcxf5yfdh", ex, "url: " + absoluteUrl);
				site = null;
			}
			return site;
		}

		/// <summary>
		/// Apply master page template to all SPWebs in a SPSite
		/// </summary>
		/// <param name="properties"></param>
		public static bool SetMaster(SPSite site, string HomepageMasterPageFilename,
			string PublishingMasterPageFilename, string NonPublishingMasterPageFilename)
		{
			bool isSuccess = true;
			try
			{
				// init
				if (site == null) { throw new Exception("SPSite passed is null"); }
				if (string.IsNullOrEmpty(HomepageMasterPageFilename) && string.IsNullOrEmpty(PublishingMasterPageFilename)
					&& string.IsNullOrEmpty(NonPublishingMasterPageFilename))
				{
					throw new Exception("No master template filename passed");
				}
				SPWebCollection allWebsites = site.AllWebs;


				for (int i = 0; i < allWebsites.Count; i++)
				{
					bool _isSuccess = true;
					using (SPWeb web = allWebsites[i])
					{
						// if homepage web, and homepage master page defined
						if (web.Url == web.Site.RootWeb.Url && !string.IsNullOrEmpty(HomepageMasterPageFilename))
						{
							_isSuccess = Web.SetMaster(web, HomepageMasterPageFilename, NonPublishingMasterPageFilename);
						}
						// for any web, where publishing or non publishing defined
						else if (!string.IsNullOrEmpty(PublishingMasterPageFilename)
							|| !string.IsNullOrEmpty(NonPublishingMasterPageFilename))
						{
							_isSuccess = Web.SetMaster(web, PublishingMasterPageFilename, NonPublishingMasterPageFilename);
						}
					}
					if (!_isSuccess) { isSuccess = false; }
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("6u7ito887rtrsedfzdsfz", ex);
				isSuccess = false;
			}
			return isSuccess;
		}


		/// <summary>
		/// Set master page template for all SPWebs in passed SPSite
		/// homepage, publishing pages, and non publishing pages will all have the passed mater page assigned
		/// </summary>
		/// <param name="site"></param>
		/// <param name="MasterPageFilename"></param>
		/// <returns></returns>
		public static bool SetMaster(SPSite site, string MasterPageFilename)
		{
			// call original
			return SetMaster(site, MasterPageFilename, MasterPageFilename, MasterPageFilename);
		}

		/// <summary>
		/// Get absolute link to site passed, including domain name
		/// </summary>
		/// <param name="site"></param>
		/// <returns></returns>
		public static string GetUrl(SPSite site)
		{
			string url = null;
			if (site != null)
			{
				url = site.Url;
				if (!string.IsNullOrEmpty(url) && url.Substring(url.Length -1) == "/")
				{
					// remove trailing slash
					url = url.Substring(0, url.Length - 1);
				}
			}
			return url;
		}


		/// <summary>
		/// Get SPSite with elevated priviledges
		/// </summary>
		/// <param name="siteId"></param>
		/// <returns></returns>
		public static SPSite GetSiteUsingElevatedPrivileges(Guid siteId)
		{
			SPSite site = null;
			try
			{
				// init
				if (siteId == null || siteId == Guid.Empty) { siteId = SPContext.Current.Site.ID; }

				// get site
				SPSecurity.RunWithElevatedPrivileges(() => { site = new SPSite(siteId); });

				if (site == null) { throw new Exception("Failed to get SPSite using elevated privileges"); }
			}
			catch (Exception ex)
			{
				SPHelper.Log.WriteError("678ti6rygffdsdfdrtrtfddcdf", ex, "siteId: " + siteId);
				site = null;
			}
			return site;
		}
		
	}
}
